<template>
  <vxe-pulldown
    ref="xDownTable"
    class="vxe-table--ignore-clear "
    style="width: 100%;padding:0;margin: 0;"
    transfer
  >
    <template #default>
      <el-input
        style="width: 100%;"
        :value="inputValue"
        :placeholder="inputPlaceholder"
        clearable
        @focus="handleInput"
        @clear="handleClearSearch"
      >
        <i
          slot="suffix"
          class="el-input__icon el-icon-search pointer"
          @click="showPanel"
        />
      </el-input>
    </template>
    <template #dropdown>
      <div
        class="erp-form-model__dropdown shadow vxe-table--ignore-clear"
        :style="{width: modalWidth, height: modalHeight}"
      >
        <div
          class="modal-box"
          :style="{width: modalWidth, height: modalHeight}"
        >
          <div class="modal-header">
            <div class="modal-header-input-box">
              <el-input
                ref="filterInput"
                v-model="filterText"
                class="modal-header-input"
                :placeholder="filterPlaceholder"
                prefix-icon="el-icon-search"
                clearable
                @input="searchEvent"
                @keyup.native.stop="handleKeyup"
                @keydown.enter.native.stop="handleKeyupEnter"
              />
              <div
                v-if="!readonly"
                class="custom-box"
              >
                <div
                  v-show="!showCustomInput"
                  class="custom-text pointer"
                  @click="changeCustomInput(true)"
                >
                  自定义输入
                </div>
                <el-input
                  v-show="showCustomInput"
                  v-model="customValue"
                  placeholder="自定义输入"
                  class="custom-input"
                  clearable
                  @keyup.enter.native="confirmCustomInput"
                />
                <el-button
                  v-show="showCustomInput"
                  type="primary"

                  @click="confirmCustomInput"
                >
                  确认
                </el-button>
              </div>
            </div>
            <div
              v-if="multiple"
              class="modal-header-confirm"
            >
              <el-button
                type="primary"
                @click="handleMultipleConfirm"
              >
                确认选择
              </el-button>
            </div>
          </div>
          <div
            class="modal-body"
            :class="{'has-footer': showFooter}"
          >
            <erp-list-page
              v-if="options"
              ref="erpListPage"
              :table-props="tablePropsCom"
              :options.sync="singleComputedOptions"
              :multiple-selected-ids="multiple ? multipleSelectedIds: []"
              :extra-data="form"
              @single-select-close="handleSingleSelect"
              @multiple-select-change="handleMultipleSelectChange"
              @multiple-select-all-change="handleMultipleSelectAllChange"
              @list-change="handleDataChange"
              @change-options="handleChangeOptions"
            />
          </div>
          <div
            v-if="showFooter"
            class="modal-footer"
          >
            <slot name="footer" />
          </div>
        </div>
      </div>
    </template>
  </vxe-pulldown>
</template>

<script>
/**
     * @Author      : maolin
     * @Date        : 2021/3/28
     * @Version     : 1.0
     * @Description :
     **/
import Vue from 'vue';
import ErpListPage from '@/components/erp/ErpListPage/ErpListPage';
import {Popover} from "element-ui";
import {cloneJson, toString} from "../../../utils";
import XEUtils from 'xe-utils';
Vue.use(Popover);
/**
 * 输入下拉表格组件
 * @author maolin
 */
export default {
  name: "ErpFormPopover",
  components: {
    ErpListPage
  },
  props: {
    /**
     * 标题
     * @public
     */
    title: {
      type: String,
      default: '',
    },
    /**
     * 字段
     * @public
     */
    field: {
      type: String,
      default: ''
    },
    /**
     * 默认值
     * @public
     */
    value: {
      type: [Number, String, Array, Object],
      default () {
        return null;
      }
    },
    /**
     * 属性
     * @public
     */
    props: {
      type: Object,
      default () {
        return {
        };
      }
    },
    /**
     * 选项
     * @public
     */
    options: {
      type: Object,
      default () {
        return {};
      }
    },
    /**
     * 额外配置
     * ```js
     * return {
          // 输入框值显示的模版
          template: '',
          // 显示底部 默认不显示
          showFooter: false,
          // 表单需要的id字段
          idField: '',
          inputPlaceholder: '',
          modalTitle: '',
          modalWidth: null,
          modalHeight: null,
          // 模态框表格中name对应的字段名
          modalNameField: null,
          // 模态框表格中id对应的字段名
          modalIdField: null,
          // 是否转换为字符串
          needToString: false,
          // 关联额外字段，除了id和name之外还需要关联字段时
          extraData: [
            // {
            //     // 外部id
            //     field: "userId",
            //     // 内部id
            //     relatedField: "id",
            // }
          ]
        }
     * ```
     * @public
     */
    extra: {
      type: Object,
      default () {
        return {
          // 输入框值显示的模版
          template: '',
          // 显示底部 默认不显示
          showFooter: false,
          // 表单需要的id字段
          idField: '',
          inputPlaceholder: '',
          modalTitle: '',
          modalWidth: null,
          modalHeight: null,
          // 模态框表格中name对应的字段名
          modalNameField: null,
          // 模态框表格中id对应的字段名
          modalIdField: null,
          // 是否转换为字符串
          needToString: false,
          // 关联额外字段，除了id和name之外还需要关联字段时
          extraData: [
            // {
            //     // 外部id
            //     field: "userId",
            //     // 内部id
            //     relatedField: "id",
            // }
          ]
        };
      }
    },
    /**
     * 表单对象
     * @public
     */
    form: {
      type: Object,
      default () {
        return {};
      }
    }
  },
  data() {
    return {
      filterText: null,
      showActiveInput: false,
      singleModalHeight: 350,
      keyword: '',
      tableHeight: 0,
      loading: false,
      visibleDialog: false,
      fullscreen: false,
      saveLoading: false,
      checkedList: null,
      tableList: [],
      selectedIds: [],
      highlightRowIndex: -1,
      customValue: '',
      showCustomInput: false,
    };
  },
  computed: {
    tablePropsCom () {
      let defaultConfig = {
        keyboardConfig: {isArrow: true},
      };
      if (this.multiple) {
        defaultConfig.checkboxConfig = {
          trigger: 'row'
        };
      }
      return defaultConfig;
    },
    inputValue () {
      let value = this.selectName;
      if (this.valueTemplate) {
        try{
          let form = this.form;
          value = new Function('form', this.valueTemplate )(form);
        }catch (e) {
          console.log(e);
        }
      }
      return value;
    },
    inputPlaceholder() {
      if (this.extra && this.extra.inputPlaceholder) {
        return this.extra.inputPlaceholder;
      }
      return '请选择';
    },
    filterPlaceholder () {
      return '输入关键字查询';
    },
    modelIdField () {
      return this.extra && this.extra.modalIdField ?  this.extra.modalIdField : null;
    },
    modelNameField () {
      return this.extra && this.extra.modalNameField ?  this.extra.modalNameField : null;
    },
    extraData () {
      return this.extra && this.extra.extraData ?   this.extra.extraData :[];
    },
    selectedList: {
      set (val) {
        this.checkedList = val;
      },
      get () {
        let ids = this.defaultIdsValue;
        let checkedList = this.checkedList;
        let check = [];
        if (checkedList === null) {
          if (ids) {
            try{
              ids = ids.split(',');
            }catch (e) {
              ids = [];
            }
            let names = this.value ? this.value.split(',') : [];
            if (ids && ids.length > 0) {
              for(let i in ids) {
                check.push({
                  [this.modelIdField]: ids[i],
                  [this.modelNameField]: names[i]
                });
              }
            }
          }
        } else {
          check = checkedList;
        }
        let data = this.tableList;
        let modelIdField = this.modelIdField;
        return check.map((item) => {
          if (data && data.length > 0) {
            for (let i in data) {
              if (data[i][modelIdField] == item[modelIdField]) {
                return data[i];
              }
            }
          }
          return item;
        });
      }
    },
    suffixIcon () {
      let suffixIcon = "el-icon-more";
      if (this.extra && this.extra.suffixIcon) {
        suffixIcon = this.extra.suffixIcon;
      }
      return suffixIcon;
    },
    defaultIdsValue () {
      let form = this.form;
      let idField = this.idField;
      return form && idField && form[idField] !== undefined ? form[idField] : '';
    },
    multipleSelectedIds () {
      let selectedList = this.selectedList;
      let array = [];
      if (selectedList && selectedList.length > 0) {
        for (let i in selectedList) {
          array.push(selectedList[i][this.modelIdField]);
        }
      }
      return array;
    },
    idField () {
      let idField = null;
      if (this.extra && this.extra.idField) {
        idField = this.extra.idField;
      }
      return idField;
    },
    readonly () {
      return this.extra && this.extra.readonly === true;
    },
    selectName: {
      get () {
        return this.value;
      },
      set (value) {
        this.$emit('value-change', value);
      }
    },
    modalTitle () {
      return this.extra && this.extra.modalTitle ?  this.extra.modalTitle : this.$t('common.select');
    },
    multiple () {
      return this.options && this.options.type === 'multipleSelect';
    },
    needToString () {
      return !!(this.extra && this.extra.needToString);
    },
    showFooter() {
      return !!(this.extra && this.extra.showFooter);
    },
    modalWidth () {
      return '600px';
    },
    modalHeight () {
      return '300px';
    },
    computedOptions:{
      get() {
        let options = cloneJson(this.options);
        options.table.height = this.tableHeight;
        return options;
      },
      set (val) {
        this.$emit('update:options', val);
      }
    },
    singleComputedOptions: {
      get() {
        let options = cloneJson(this.options);
        options.table.showHeader = false;
        if (this.showFooter) {
          options.table.height = '174px';
        } else {
          options.table.height = '212px';
        }
        options.table.padding = '0';
        return options;
      },
      set (val) {
        this.$emit('update:options', val);
      }
    },
    valueTemplate () {
      return this.extra && this.extra.template ? this.extra.template : null;
    },
  },
  watch: {
    defaultIdsValue (defaultIdsValue) {
      this.selectedIds = toString(defaultIdsValue) ? (toString(defaultIdsValue)).split(',') : [];
    },
  },
  created() {
  },
  mounted() {
  },
  methods: {
    /**
     * 触发清除
     * @private
     */
    handleClear () {
      if (this.modelIdField) {
        this.updateIdField(this.idField, null);
      }
      if (this.extraData && this.extraData.length > 0) {
        for (let i in this.extraData) {
          this.updateIdField(this.extraData[i].field, null);
        }
      }
      this.selectName = "";
    },
    /**
     * 清除搜索
     * @private
     */
    handleClearSearch () {
      this.handleClear();
      this.searchList('');
    },
    /**
     * 显示下拉框
     * @public
     */
    showPanel () {
      this.$refs.xDownTable.showPanel();
    },
    /**
     * 隐藏下拉框
     * @public
     */
    hidePanel () {
      this.$refs.xDownTable.hidePanel();
    },
    /**
     * 搜索列表
     * @public
     */
    searchList (value) {
      let searchOptions = this.options.search;
      let field = searchOptions && searchOptions.keywordKey ? searchOptions.keywordKey : 'name';
      let json = {};
      json[field] = this.filterText;
      this.$refs.erpListPage && this.$refs.erpListPage.handleSearch({search: json});
    },
    /**
     * 更新是否显示自定义输入
     * @private
     */
    changeCustomInput (bool) {
      this.showCustomInput = bool;
    },
    /**
     * 搜索事件的防跳反策略
     * @private
     */
    searchEvent: XEUtils.debounce(function () {
      this.searchList();
    }, 200, { leading: false, trailing: true }),
    /**
     * 选择单选
     * @private
     * @param {object} data 选择的表格行{item}
     */
    handleSingleSelectClose (data) {
      let item = data.item;
      if (this.modelIdField) {
        this.updateIdField(this.idField, item[this.modelIdField] || null);
      }
      if (this.extraData && this.extraData.length > 0) {
        for (let i in this.extraData) {
          this.updateIdField(this.extraData[i].field, item[this.extraData[i].relatedField] || null);
        }
      }
      if (this.modelNameField) {
        this.selectName = item[this.modelNameField] || null;
      }
      this.handleCloseModal();
    },
    /**
     * 选择单选
     * @private
     * @param {object} data 选择的表格行{item}
     */
    handleSingleSelect (data) {
      let item = data.item;
      if (this.modelIdField) {
        this.updateIdField(this.idField, item[this.modelIdField] || null);
      }
      if (this.extraData && this.extraData.length > 0) {
        for (let i in this.extraData) {
          this.updateIdField(this.extraData[i].field, item[this.extraData[i].relatedField] || null);
        }
      }
      if (this.modelNameField) {
        this.selectName = item[this.modelNameField] || null;
      }
      
      this.$emit('single-select', {item : item, form: this.form});
      this.hidePanel();
    },
    /**
     * 多选
     * @private
     * @param {object} data 多选选中的数据{selection}
     */
    handleMultipleSelectChange (data) {
      let checked = false;
      if (data.selection && data.selection.length > 0) {
        for (let i in data.selection) {
          if (data.selection[i][this.modelIdField] == data.row[this.modelIdField]) {
            checked = true;
            break;
          }
        }
      }
      this.selectedIds = [data.row[this.modelIdField]];
      this.multipleSelectChange([data.row], checked);

    },
    /**
     * 全选
     * @private
     * @param {array} data 数据{selection}
     */
    handleMultipleSelectAllChange (data) {
      let checked = false;
      let list = cloneJson(this.tableList);
      if (data.selection && data.selection.length > 0) {
        checked = true;
        list = data.selection;
      }
      this.multipleSelectChange(list, checked);
    },
    /**
     * 表格数据更新
     * @private
     * @param {array} data 表格列表数据
     */
    handleDataChange (data) {
      this.tableList = data;
    },
    /**
     * 更新下拉表格配置
     * @private
     * @param {object} options 表格配置对象
     */
    handleChangeOptions (options) {
      this.computedOptions = options;
    },
    /**
     * 触发输入框
     * @private
     * @param {object} e 输入框对象
     */
    handleInput (e) {
      this.showPanel();
      this.$nextTick(() => {
        this.$refs.filterInput.focus();
        let value = e.target.value;
        if (this.selectName) {
          value = this.selectName;
        }
        this.filterText = value;
        // this.searchEvent()
      });
    },
    /**
     * 更新表单其他值
     * @private
     * @param {string} field 字段
     * @param {*} val 值
     */
    updateIdField (field, val) {
      if (this.needToString) {
        val = toString(val);
      }
      this.$emit('update-id-field', {[field]: val});
    },
    /**
     * 键盘弹出触发
     * @private
     * @param {object} e
     */
    handleKeyup (e) {
      if (e.keyCode === 13) {
        this.handleKeyupEnter();
      } else if (e.keyCode === 40) {
        this.tableRowMove('down');
      } else if (e.keyCode === 38) {
        this.tableRowMove('up');
      } else {
        this.highlightRowIndex = -1;
        this.showPanel();
        if (this.modelIdField) {
          this.updateIdField(this.idField, null);
        }
        if (this.extraData && this.extraData.length > 0) {
          for (let i in this.extraData) {
            this.updateIdField(this.extraData[i].field, null);
          }
        }
      }
    },
    /**
     * 多选确认
     * @private
     */
    handleMultipleConfirm () {
      this.$emit('multiple-insert', {rows: this.selectedList});
      this.hidePanel();
    },
    /**
     * 在下拉表格内输入enter，选择选中行，若没有选中行，则为第一行
     * @private
     */
    handleKeyupEnter () {
      let data = this.tableList;
      if (data && data.length > 0 ) {
        if (this.highlightRowIndex < 0) {
          this.highlightRowIndex = 0;
        }
        this.handleSingleSelect({item: data[this.highlightRowIndex]});
      }
    },
    /**
     * 勾选多选复选框触发
     * @private
     * @param {array} data 当前勾选的数据
     * @param {boolean} checked 是否选中
     */
    multipleSelectChange (data, checked) {
      let idField = this.modelIdField;
      let checkedList = cloneJson(this.selectedList);
      if (idField && data && data.length > 0) {
        if (checked) {
          checkedList = checkedList.concat(data);
          let obj = {};
          checkedList = checkedList.reduce((cur, next) => {
            obj[next[idField]] ? "" : obj[next[idField]] = true && cur.push(next);
            return cur;
          }, []);
        } else {
          let newCheckedList = [];
          for (let i in checkedList) {
            let isDelete = false;
            for (let j in data) {
              if (checkedList[i][idField] === data[j][idField]) {
                isDelete = true;
                break;
              }
            }
            if (!isDelete) {
              newCheckedList.push(checkedList[i]);
            }
          }
          checkedList = newCheckedList;
        }
      }
      this.selectedList = checkedList;

    },
    /**
     * 高亮结果行，上下移动
     * @private
     * @param direction
     */
    tableRowMove (direction) {
      let tableList = this.tableList;
      if (tableList && tableList.length > 0) {
        let tableLength = tableList.length;
        if (direction === 'down') {
          if (this.highlightRowIndex >= tableLength - 1) {
            this.highlightRowIndex = tableLength - 1;
          } else {
            this.highlightRowIndex ++;
          }
          this.$refs.erpListPage.$refs.erpPageTable.$refs.table.$refs.erpTable.setCurrentRow(tableList[this.highlightRowIndex]);
        } else if (direction === 'up') {
          if (this.highlightRowIndex <= 0) {
            this.highlightRowIndex = 0;
          } else {
            this.highlightRowIndex --;
          }
          this.$refs.erpListPage.$refs.erpPageTable.$refs.table.$refs.erpTable.setCurrentRow(tableList[this.highlightRowIndex]);
        }
      }

    },
    /**
     * 确认自定义输入值
     * @private
     */
    confirmCustomInput () {
      this.selectName = this.customValue;
      if (this.modelIdField) {
        this.updateIdField(this.idField, null);
      }
      if (this.extraData && this.extraData.length > 0) {
        for (let i in this.extraData) {
          this.updateIdField(this.extraData[i].field, null);
        }
      }
      this.hidePanel();
    }
  },
};
</script>

<style lang="scss" scoped>
    .modal-box{
        height: 100%;
        background-color: #f6f6f6;
        border: 1px solid #b1b1b1;
        .modal-header{
            height: 38px;
            border-bottom: 1px solid #dddbdc;
            display: flex;
            flex-wrap: nowrap;
            .modal-header-input-box{
                width: calc(100% - 100px);
                padding: 5px;
                display: flex;
                flex-wrap: nowrap;
                .modal-header-input{
                    height: 28px;
                    max-width: 200px;
                }
                .custom-box{
                    margin-left: 20px;
                    display: flex;
                    .custom-text{
                        color: var(--primary-color);
                        line-height: 28px;
                        font-size: var(--font-size);
                    }
                    .custom-input{
                        height: 28px;
                        max-width: 120px;
                    }
                }
            }
            .modal-header-confirm{
                width: 100px;
                text-align: right;
                height: 28px;
                padding: 5px;
            }
        }
        .modal-footer{
            height: 38px;
            border-top: 1px solid #dddbdc;
        }
        .modal-body{
            background-color: #fff;
            height: calc(100% - 38px);
            &.has-footer{
                height: calc(100% - 76px);
            }
        }

    }

</style>
